package learnIgnite.cluster.cluster;

import java.util.Arrays;

import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCluster;
import org.apache.ignite.Ignition;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi;
import org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder;
import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder;
import org.apache.ignite.spi.discovery.tcp.ipfinder.zk.TcpDiscoveryZookeeperIpFinder;

/**
 * 集群节点的自组网---tcp和zookeeper
 * @author yangcheng  
 * @date 2019年8月29日  
 * @version V1.0
 */
public class TestCluster {

	public static void init(){
		Ignite ignite = Ignition.ignite();
		/**
		 * 	通过IgniteCluster接口可以：
		      	启动和停止一个远程集群节点；
		      	获取集群成员的列表；
		      	创建逻辑集群组
		 */
		IgniteCluster cluster = ignite.cluster();
	}
	
	//----------------------------------------TCP方式---------------------------------------------------
	
	
	/**
	 * 基于组播方式自动发现并建立集群
	 *  实例  ： 执行两次当前方法，则控制台最后会提示连个server组网成功
	 *  [10:10:14] Ignite node started OK (id=68a47e02)
		[10:10:14] Topology snapshot [ver=1, locNode=68a47e02, servers=1, clients=0, state=ACTIVE, CPUs=12, offheap=3.2GB, heap=3.5GB]
		[10:10:17] Joining node doesn't have encryption data [node=2ba6c146-bf15-42fa-802c-f5cb12990a90]
		[10:10:17] Topology snapshot [ver=2, locNode=68a47e02, servers=2, clients=0, state=ACTIVE, CPUs=12, offheap=6.3GB, heap=7.1GB]
		
		当再次启动第三个server时，控制台会新增打印：
		[10:16:42] Joining node doesn't have encryption data [node=49654e7a-a7da-47c5-a89e-0d8bde13734c]
		[10:16:42] Topology snapshot [ver=3, locNode=68a47e02, servers=3, clients=0, state=ACTIVE, CPUs=12, offheap=9.5GB, heap=11.0GB]
		表示现在集群中存在三个ignite的server节点了
	 */
	public static void TCPDiscovry(){
		TcpDiscoverySpi spi = new TcpDiscoverySpi();

		TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();

		/**
		 * 组播地址范围“224.0.0.0 - 239.255.255.255”
		 */
		ipFinder.setMulticastGroup("224.8.8.8");

		spi.setIpFinder(ipFinder);

		IgniteConfiguration cfg = new IgniteConfiguration();

		// Override default discovery SPI.
		cfg.setDiscoverySpi(spi);

		// Start Ignite node.
		Ignition.start(cfg);
	}
	
	/**
	 * 基于静态IP实现server的集群
	 */
	public static void TCPDiscovryByDetailIP(){
		TcpDiscoverySpi spi = new TcpDiscoverySpi();

		TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder();

		// Set initial IP addresses.
		// Note that you can optionally specify a port or a port range.
//		ipFinder.setAddresses(Arrays.asList("1.2.3.4", "1.2.3.5:47500..47509"));
		ipFinder.setAddresses(Arrays.asList("172.30.96.79"));

		spi.setIpFinder(ipFinder);

		IgniteConfiguration cfg = new IgniteConfiguration();

		// Override default discovery SPI.
		cfg.setDiscoverySpi(spi);

		// Start Ignite node.
		Ignition.start(cfg);
	}
	
	
	/**
	 * 同时使用基于组播和静态IP的发现，这种情况下，除了通过组播接受地址以外，
	 * 如果有，TcpDiscoveryMulticastIpFinder也可以与预配置的静态IP地址列表一起工作
	 */
	public static void  TCPDiscovryBoth(){
		TcpDiscoverySpi spi = new TcpDiscoverySpi();

		TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder();

		// Set Multicast group.
		ipFinder.setMulticastGroup("228.10.10.157");

		// Set initial IP addresses.
		// Note that you can optionally specify a port or a port range.
		ipFinder.setAddresses(Arrays.asList("1.2.3.4", "1.2.3.5:47500..47509"));

		spi.setIpFinder(ipFinder);

		IgniteConfiguration cfg = new IgniteConfiguration();

		// Override default discovery SPI.
		cfg.setDiscoverySpi(spi);

		// Start Ignite node.
		Ignition.start(cfg);
	}
	
	//----------------------------------------zookeeper方式---------------------------------------------------
	/**
	 * zookeeper得节点路径为：/services/ignite
	 * 
	 * 需要注意guava得版本冲突
	 * 
	 * ZooKeeper发现机制是为需要保证伸缩性和线性扩展的大规模Ignite集群而设计的。
	 * 但是同时使用Ignite和ZooKeeper需要配置和管理两个分布式系统，这很有挑战性。
	 * 因此，建议仅在打算扩展到成百或者上千个节点时才使用该发现机制。否则，最好使用TCP/IP发现。
	 */
	public static void  TCPDiscovryByZK(){
		TcpDiscoverySpi spi = new TcpDiscoverySpi();

		TcpDiscoveryZookeeperIpFinder ipFinder = new TcpDiscoveryZookeeperIpFinder();

		// Specify ZooKeeper connection string.
		ipFinder.setZkConnectionString("127.0.0.1:2181");

		spi.setIpFinder(ipFinder);

		IgniteConfiguration cfg = new IgniteConfiguration();

		// Override default discovery SPI.
		cfg.setDiscoverySpi(spi);

		// Start Ignite node.
		Ignition.start(cfg);
	}
	
	
	public static void main(String[] args) {
//		TCPDiscovry();
//		TCPDiscovryByDetailIP();
		TCPDiscovryByZK();
	} 
	
}
